Nachdem wir uns nun letzte Woche bereits angeschaut haben, wie man als Client mit einem Server
kommunizieren kann, wollen wir dieses Mal die Gegenseite betrachten und einen Server
implementieren.
Dazu schauen wir uns direkt die Schnittstelle an, die uns das Betriebssystem zur Verfügung
stellt.
Wir gehen jetzt einmal davon aus, dass wir bereits ein Socket erstellt haben, an dem
wir angegeben haben, was für eine Verbindung verwendet werden soll.
Der zweite Schritt für ein Server ist nun, dieses Socket an eine neue Adresse zu binden.
Die Adresse bedeutet in dem Fall zum Beispiel, auf welche IP-Adresse gelauscht werden soll
und welcher Port verwendet werden soll.
Dies ist aber abhängig vom Socket und kann im Falle eines Unix-Sockets, das zum Beispiel
rein lokal ist, auch nur der Pfad zu diesem Socket sein.
Um nun das Socket an eine bestimmte Adresse zu binden, können wir den Bind-Systemaufruf
verwenden.
Dieser bekommt als erstes Argument eben das Socket, das verwendet werden soll.
Die beiden anderen Argumente bezeichnen die Adresse, nehme ich ein Zeiger auf eine Datenstruktur,
die die Adresse beschreibt und die Adr-Länge bezeichnet nun die Größe der Struktur.
Das interessante an der Stelle ist nun, dass die Struktur SockAdr eigentlich gar nicht
in der Lage ist, die notwendigen Informationen über die Adresse zu speichern, da die einzigen
Strukturmitglieder einmal die SA-Family sind, die beschreibt um was für ein Socket es sich
handelt und ein Platzhalter für eine andere Adresse.
Dies liegt daran, dass hier eine Art Klassenvererbung verwendet wird.
Tatsächlich gibt es verschiedene Strukturen, je eine für eine bestimmte Art von Socket.
Diese haben nur gemein, dass das erste Strukturmitglied jeweils die SA-Family ist.
Die restlichen Strukturmitglieder sind jeweils verschieden.
Damit der Systemaufruf aber dennoch eine einheitliche Schnittstelle bietet und nur einmal implementiert
werden muss, werden all die verschiedenen Strukturen, die es für die Sockets gibt, nun
auf einen in Anführungsstrichen gemeinsamen Typen zurückgeführt, der hier als Argument
übergeben wird.
Also wollen wir uns im nächsten Schritt einmal anschauen, was für konkrete Adressstrukturen
es gibt.
Dabei fangen wir bei IPv4 Sockets an.
Dafür wird die konkrete Struktur SockAdr in verwendet, die die Strukturmitglieder SinFamily,
Port und SinAdr bietet.
Das Strukturmitglied SinPort speichert den Port, auf dem gelauscht werden soll, während
SinAdr beschreibt, welche lokale Adresse genutzt werden soll.
Damit wählt man effektiv das Netzwerkinterface aus.
Möchte man auf allen verfügbaren Netzwerkschnittstellen lauschen, kann man hier die Konstante in
AdrAny einsetzen.
Es ist nicht unüblich, dass man auf seinem Computer mehrere Netzwerkschnittstellen hat.
Für gewöhnlich haben zum Beispiel Laptops mindestens zwei, einmal eine Netzwerkkarte,
über die man das Ethernet-Kabel ansteckt und oft noch ein zweites Interface für WLAN.
Dies sind zwei getrennte Geräte, die jeweils eine eigene Netzwerkschnittstelle anbieten.
Manchmal hat man auch noch Netzwerkschnittstellen, die durch Software entstehen, zum Beispiel
wenn man einen VPN nutzt.
Dementsprechend kann man nun mit dem Strukturmitglied SinAdr auswählen, über welches dieser Interfaces
kommuniziert werden soll.
Betreffend des Ports müssen wir nun die N-DNS beachten.
Der Port wird immer in der NetzwerkbyteOrder angegeben.
Dementsprechend müssen wir, wenn wir den Port setzen wollen, eine Konvertierung der Host
Zugänglich über
Offener Zugang
Dauer
00:12:36 Min
Aufnahmedatum
2020-11-15
Hochgeladen am
2020-11-15 19:39:05
Sprache
de-DE